<?php

namespace app\admin\model;
use think\Model;

class ClassSequence extends Model
{
    // 表名
    public $name = 'class_sequence';
    public $prefix_new = 'fa_';
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'datetime';

    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    public $data;

    /**
     * 获取下一个序号
     * @param int $classType 班级类型 1=学校班级 2=社区班级
     * @return int
     */
    public static function getNextSequence($classType)
    {
        $maxSequence = self::where('class_type', $classType)
            ->where('status', 1)
            ->max('sequence_number');
        
        return $maxSequence ? $maxSequence + 1 : 1;
    }

    /**
     * 为班级分配序号
     * @param int $classId 班级ID
     * @param int $classType 班级类型
     * @param int $schoolId 学校ID
     * @param int $communityId 社区ID
     * @return bool
     */
    public static function assignSequence($classId, $classType, $schoolId = null, $communityId = null)
    {
        // 检查是否已经分配过序号
        $existing = self::where('class_id', $classId)->find();
        if ($existing) {
            return true; // 已经分配过序号
        }

        // 使用事务确保原子性
        \think\Db::startTrans();
        try {
            // 获取当前最大序号并加锁，防止并发问题
            $maxSequence = \think\Db::table('fa_class_sequence')
                ->where('class_type', $classType)
                ->where('status', 1)
                ->max('sequence_number');
            
            $sequenceNumber = $maxSequence ? $maxSequence + 1 : 1;
            
            $data = [
                'class_id' => $classId,
                'sequence_number' => $sequenceNumber,
                'class_type' => $classType,
                'school_id' => $schoolId,
                'community_id' => $communityId,
                'status' => 1,
                'weigh' => 0,
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ];

            // 尝试插入记录
            $result = \think\Db::table('fa_class_sequence')->insert($data);
            
            if (!$result) {
                throw new \Exception('插入序号记录失败');
            }
            
            \think\Db::commit();
            return true;
        } catch (\Exception $e) {
            \think\Db::rollback();
            
            // 如果是唯一键冲突，可能是并发问题，重试一次
            if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
                // 短暂延迟后重试
                usleep(100000); // 100毫秒
                return self::assignSequence($classId, $classType, $schoolId, $communityId);
            }
            
            return false;
        }
    }

    /**
     * 根据班级ID获取序号
     * @param int $classId
     * @return int|null
     */
    public static function getSequenceByClassId($classId)
    {
        $result = self::where('class_id', $classId)
            ->where('status', 1)
            ->value('sequence_number');
        
        return $result;
    }

    /**
     * 根据班级类型和序号获取班级ID
     * @param int $classType 班级类型
     * @param int $sequenceNumber 序号
     * @return int|null
     */
    public static function getClassIdBySequence($classType, $sequenceNumber)
    {
        $result = self::where('class_type', $classType)
            ->where('sequence_number', $sequenceNumber)
            ->where('status', 1)
            ->value('class_id');
        
        return $result;
    }

    /**
     * 初始化班级序号
     * 根据班级创建时间顺序分配序号
     * @return bool
     */
    public static function initializeSequences()
    {
        // 清空序号表
        self::where('id', '>', 0)->delete();
        
        // 获取所有学校班级，按创建时间排序
        $schoolClasses = \app\admin\model\Classes::where('classes_type', 1)
            ->order('id asc') // 使用ID排序替代创建时间排序
            ->select();
        
        // 获取所有社区班级，按创建时间排序
        $communityClasses = \app\admin\model\Classes::where('classes_type', 2)
            ->order('id asc') // 使用ID排序替代创建时间排序
            ->select();
        
        // 为学校班级分配序号
        $schoolSequence = 1;
        foreach ($schoolClasses as $class) {
            $data = [
                'class_id' => $class->id,
                'sequence_number' => $schoolSequence,
                'class_type' => 1,
                'school_id' => $class->school_id,
                'community_id' => null,
                'status' => 1,
                'weigh' => 0,
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ];
            
            $model = new self();
            $model->save($data);
            
            $schoolSequence++;
        }
        
        // 为社区班级分配序号
        $communitySequence = 1;
        foreach ($communityClasses as $class) {
            $data = [
                'class_id' => $class->id,
                'sequence_number' => $communitySequence,
                'class_type' => 2,
                'school_id' => null,
                'community_id' => $class->community_id,
                'status' => 1,
                'weigh' => 0,
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ];
            
            $model = new self();
            $model->save($data);
            
            $communitySequence++;
        }
        
        return true;
    }

    /**
     * 获取班级类型文本
     */
    public function getClassTypeTextAttr($value, $data)
    {
        $list = ['1' => '学校班级', '2' => '社区班级'];
        return isset($list[$data['class_type']]) ? $list[$data['class_type']] : '';
    }

    /**
     * 获取状态文本
     */
    public function getStatusTextAttr($value, $data)
    {
        $list = ['0' => '失效', '1' => '正常'];
        return isset($list[$data['status']]) ? $list[$data['status']] : '';
    }
    
    /**
     * 获取格式化的序号（带前缀）
     * @param int $classType 班级类型
     * @param int $sequenceNumber 序号
     * @return string
     */
    public static function getFormattedSequence($classType, $sequenceNumber)
    {
        $prefix = $classType == 1 ? 'S-' : 'C-';
        return $prefix . str_pad($sequenceNumber, 3, '0', STR_PAD_LEFT);
    }
    
    /**
     * 获取班级的格式化序号
     * @param int $classId 班级ID
     * @return string|null
     */
    public static function getFormattedSequenceByClassId($classId)
    {
        $sequence = self::where('class_id', $classId)->where('status', 1)->find();
        if (!$sequence) {
            return null;
        }
        
        return self::getFormattedSequence($sequence['class_type'], $sequence['sequence_number']);
    }
    
    /**
     * 重新分配班级序号（当班级类型改变时）
     * @param int $classId 班级ID
     * @param int $newClassType 新的班级类型
     * @param int $schoolId 学校ID
     * @param int $communityId 社区ID
     * @return bool
     */
    public static function reassignSequence($classId, $newClassType, $schoolId = null, $communityId = null)
    {
        // 使用事务确保原子性
        \think\Db::startTrans();
        try {
            // 获取旧的序号记录
            $oldSequence = self::where('class_id', $classId)->find();
            
            // 删除旧的序号
            if ($oldSequence) {
                $oldSequence->delete();
            }
            
            // 获取当前最大序号并加锁，防止并发问题
            $maxSequence = \think\Db::table('fa_class_sequence')
                ->where('class_type', $newClassType)
                ->where('status', 1)
                ->max('sequence_number');
            
            $sequenceNumber = $maxSequence ? $maxSequence + 1 : 1;
            
            $data = [
                'class_id' => $classId,
                'sequence_number' => $sequenceNumber,
                'class_type' => $newClassType,
                'school_id' => $schoolId,
                'community_id' => $communityId,
                'status' => 1,
                'weigh' => 0,
                'create_time' => date('Y-m-d H:i:s'),
                'update_time' => date('Y-m-d H:i:s')
            ];

            // 尝试插入记录
            $result = \think\Db::table('fa_class_sequence')->insert($data);
            
            if (!$result) {
                throw new \Exception('插入序号记录失败');
            }
            
            \think\Db::commit();
            return true;
        } catch (\Exception $e) {
            \think\Db::rollback();
            
            // 如果是唯一键冲突，可能是并发问题，重试一次
            if (strpos($e->getMessage(), 'Duplicate entry') !== false) {
                // 短暂延迟后重试
                usleep(100000); // 100毫秒
                return self::reassignSequence($classId, $newClassType, $schoolId, $communityId);
            }
            
            return false;
        }
    }
    
    /**
     * 检查序号表与班级表的一致性
     * @return array 不一致的记录
     */
    public static function checkConsistency()
    {
        $inconsistencies = [];
        
        // 检查序号表中的班级是否都存在
        $sequences = self::select();
        foreach ($sequences as $sequence) {
            $class = \app\admin\model\Classes::get($sequence['class_id']);
            if (!$class) {
                $inconsistencies[] = [
                    'type' => 'orphaned_sequence',
                    'sequence_id' => $sequence['id'],
                    'class_id' => $sequence['class_id']
                ];
                continue;
            }
            
            // 检查班级类型是否一致
            if ($class['classes_type'] != $sequence['class_type']) {
                $inconsistencies[] = [
                    'type' => 'type_mismatch',
                    'sequence_id' => $sequence['id'],
                    'class_id' => $sequence['class_id'],
                    'sequence_type' => $sequence['class_type'],
                    'class_type' => $class['classes_type']
                ];
            }
        }
        
        // 检查是否有班级没有序号
        $classes = \app\admin\model\Classes::select();
        foreach ($classes as $class) {
            $sequence = self::where('class_id', $class['id'])->find();
            if (!$sequence) {
                $inconsistencies[] = [
                    'type' => 'missing_sequence',
                    'class_id' => $class['id'],
                    'class_type' => $class['classes_type']
                ];
            }
        }
        
        return $inconsistencies;
    }
    
    /**
     * 修复序号表与班级表的不一致
     * @return array 修复结果
     */
    public static function fixConsistency()
    {
        $result = [
            'orphaned_removed' => 0,
            'type_fixed' => 0,
            'missing_added' => 0
        ];
        
        $inconsistencies = self::checkConsistency();
        
        foreach ($inconsistencies as $item) {
            switch ($item['type']) {
                case 'orphaned_sequence':
                    // 删除孤立的序号记录
                    self::where('id', $item['sequence_id'])->delete();
                    $result['orphaned_removed']++;
                    break;
                    
                case 'type_mismatch':
                    // 修复类型不匹配
                    $class = \app\admin\model\Classes::get($item['class_id']);
                    self::reassignSequence(
                        $item['class_id'], 
                        $class['classes_type'], 
                        $class['school_id'], 
                        $class['community_id']
                    );
                    $result['type_fixed']++;
                    break;
                    
                case 'missing_sequence':
                    // 为缺失的班级添加序号
                    $class = \app\admin\model\Classes::get($item['class_id']);
                    self::assignSequence(
                        $item['class_id'], 
                        $class['classes_type'], 
                        $class['school_id'], 
                        $class['community_id']
                    );
                    $result['missing_added']++;
                    break;
            }
        }
        
        return $result;
    }
}